﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using NetDon.OA.Data.CollectionClasses;
using NetDon.OA.Data.EntityClasses;
using NetDon.OA.Data.HelperClasses;
using NetDon.OA.Data.Linq;
using NetDon.OA.Interface;
using NetDon.OA.Interface.CRM;
using NetDon.OA.Interface.Common;
using SD.LLBLGen.Pro.ORMSupportClasses;

namespace NetDon.OA.Business.Common
{
    public class GoodsTravelDaysConfigService : IGoodsTravelDaysConfigService
    {

        public void AppendGoodsTravelDaysConfig(Guid areaId, Guid routeTypeId, string deliveryCity, string province, decimal? unitCost = 0, decimal? revenueUnitCost = 0)
        {
            if (string.IsNullOrWhiteSpace(deliveryCity) || string.IsNullOrWhiteSpace(province))
                return;

            var meta = new LinqMetaData();

           if (!CheckGoodsTravelDaysConfigExists(Guid.Empty, routeTypeId, deliveryCity, areaId))
            {
                var data = new GoodsTravelDaysConfigData()
                {
                    AreaId = areaId,
                    RouteTypeId = routeTypeId,
                    DeliveryProvince = province,
                    DeliveryCity = deliveryCity,
                    GoodsTravelDaysUnit = 0,
                    ReceiptOnWayDaysUnit = 0,
                    GoodsTravelDays = 0,
                    ReceiptOnWayDays = 0,
                    UnitCost = unitCost,
                    RevenueUnitCost = revenueUnitCost,
                    Id = Guid.NewGuid()
                };
                AddGoodsTravelDaysConfig(data);
            }
 

        }
        public bool AddGoodsTravelDaysConfig(GoodsTravelDaysConfigData goodsTravelDaysConfigData)
        {
            var entity = ConvertToEntityByBusinessData(goodsTravelDaysConfigData, true);
            return entity.Save();
        }

        public bool ModifyGoodsTravelDaysConfig(GoodsTravelDaysConfigData goodsTravelDaysConfigData)
        {
            var entity = ConvertToEntityByBusinessData(goodsTravelDaysConfigData, false);
            return entity.Save();
        }

        public bool RemoveGoodsTravelDaysConfig(Guid goodsTravelDaysConfigId)
        {
            var attachmentsCollection = new GoodsTravelDaysConfigCollection();
            int result = attachmentsCollection.DeleteMulti(GoodsTravelDaysConfigFields.Id == goodsTravelDaysConfigId);
            return result > 0;
        }

        public GoodsTravelDaysConfigData GetGoodsTravelDaysConfigById(Guid goodsTravelDaysConfigId)
        {
            var meta = new LinqMetaData();
            var linqResult = (from q in meta.GoodsTravelDaysConfig
                              where q.Id == goodsTravelDaysConfigId
                              select q).FirstOrDefault();

            if (linqResult != null)
            {
                return ConvertToBusinessDataByEntity(linqResult);
            }

            return null;
        }

        public List<GoodsTravelDaysConfigData> GetGoodsTravelDaysConfigs()
        {
            var meta = new LinqMetaData();
            var listResult = from q in meta.GoodsTravelDaysConfig
                             select q;
            List<GoodsTravelDaysConfigData> listAttachments = new List<GoodsTravelDaysConfigData>();
            if (listResult != null && listResult.Count() > 0)
            {
                foreach (var attachmentsEntity in listResult)
                {
                    var obj = ConvertToBusinessDataByEntity(attachmentsEntity);
                    if (obj != null)
                    {
                        listAttachments.Add(obj);
                    }
                }
            }

            return listAttachments;
        }



        private GoodsTravelDaysConfigEntity ConvertToEntityByBusinessData(GoodsTravelDaysConfigData routeData, bool isAdd)
        {
            GoodsTravelDaysConfigEntity entity = null;
            if (isAdd)
            {
                entity = new GoodsTravelDaysConfigEntity();
                entity.Id = routeData.Id;
                if (entity.Id == Guid.Empty)
                {
                    entity.Id = Guid.NewGuid();
                }
            }
            else
            {
                entity = new GoodsTravelDaysConfigEntity(routeData.Id);
            }
            entity.AreaId = routeData.AreaId;
            entity.RouteTypeId = routeData.RouteTypeId;
            entity.DeliveryCity = routeData.DeliveryCity;
            entity.GoodsTravelDays = routeData.GoodsTravelDays;
            entity.DeliveryProvince = routeData.DeliveryProvince;
            entity.GoodsTravelDaysUnit = routeData.GoodsTravelDaysUnit;
            entity.ReceiptOnWayDays = routeData.ReceiptOnWayDays;
            entity.ReceiptOnWayDaysUnit = routeData.ReceiptOnWayDaysUnit;
            entity.UnitCost = routeData.UnitCost;
            entity.RevenueUnitCost = routeData.RevenueUnitCost;
            return entity;
        }

        private GoodsTravelDaysConfigData ConvertToBusinessDataByEntity(GoodsTravelDaysConfigEntity routeEntity)
        {
            return new GoodsTravelDaysConfigData
            {
                Id = routeEntity.Id,
                AreaId = routeEntity.AreaId,
                DeliveryCity = routeEntity.DeliveryCity,
                RouteTypeId = routeEntity.RouteTypeId,
                GoodsTravelDays = routeEntity.GoodsTravelDays,
                DeliveryProvince = routeEntity.DeliveryProvince,
                GoodsTravelDaysUnit = routeEntity.GoodsTravelDaysUnit,
                ReceiptOnWayDays = routeEntity.ReceiptOnWayDays,
                ReceiptOnWayDaysUnit = routeEntity.ReceiptOnWayDaysUnit,
                UnitCost = routeEntity.UnitCost,
                DeliveryCityName = new CityEntity(routeEntity.DeliveryCity).Name,
                DeliveryProvinceName = new ProvinceEntity(routeEntity.DeliveryProvince).Name,
                RevenueUnitCost = routeEntity.RevenueUnitCost

            };
        }


        public int GetGoodsTravelDaysConfigCount(GoodsTravelDaysConfigSearchCriteria criteria)
        {
            var collection = new GoodsTravelDaysConfigCollection();
            return collection.GetDbCount(GetSearchGoodsTravelDaysConfigPredicate(criteria));
        }

        public IEnumerable<GoodsTravelDaysConfigData> SearchGoodsTravelDaysConfigDatasByCondition(GoodsTravelDaysConfigSearchCriteria criteria, string sortExpression, System.Web.UI.WebControls.SortDirection sortDirection, int pageSize, int pageIndex)
        {
            var sort = GetSortExpression(sortExpression, sortDirection);
            var collection = new GoodsTravelDaysConfigCollection();
            collection.GetMulti(GetSearchGoodsTravelDaysConfigPredicate(criteria), 0, sort,
                              null, pageIndex + 1, pageSize);

            var result = from customerInfo in collection
                         select ConvertToBusinessDataByEntity(customerInfo);


            return result;
        }

        public GoodsTravelDaysConfigData GetGoodsTravelDaysConfigDatasByCondition(GoodsTravelDaysConfigSearchCriteria criteria)
        {
            var collection = new GoodsTravelDaysConfigCollection();
            collection.GetMulti(GetSearchGoodsTravelDaysConfigPredicate(criteria));
            return (from customerInfo in collection
                    select ConvertToBusinessDataByEntity(customerInfo)).FirstOrDefault();
        }

        public GoodsTravelDaysConfigData GetGoodsTravelDaysConfigDatasByCondition(IEnumerable<IssuingOrderDeliveryData> issuingOrderDeliveries, IssuingOrderData issuingOrderData)
        {
            GoodsTravelDaysConfigData from = null;
            foreach (var issuingOrderDelivery in issuingOrderDeliveries)
            {
                var data = GetGoodsTravelDaysConfigDatasByCondition(
                     new GoodsTravelDaysConfigSearchCriteria()
                         {
                             AreaId = issuingOrderData.AreaId,
                             DeliveryCity = issuingOrderDelivery.DeliveryCity,
                             RouteTypeId = issuingOrderData.RouteTypeId
                         });
                from = CompareGoodsTravelDaysConfig(from, data);

            }
            return from;
        }

        private GoodsTravelDaysConfigData CompareGoodsTravelDaysConfig(GoodsTravelDaysConfigData from, GoodsTravelDaysConfigData to)
        {
            if (from == null) return to;
            if (to == null) return from;
            int totalFromHours = from.GoodsTravelDays??0;
            int totalToHours= to.GoodsTravelDays??0;

            if (from.GoodsTravelDaysUnit == 0)
            {
                totalFromHours = from.GoodsTravelDays ?? 0 * 24;
               

            }
            if (from.GoodsTravelDaysUnit == 0)
            {
                totalToHours = to.GoodsTravelDays ?? 0 * 24;

            }
            return totalFromHours > totalToHours ? from : to;
        }

        private SortExpression GetSortExpression(string strInput, SortDirection sortDirection)
        {
            SortExpression sort;
            switch (strInput)
            {
                case "RouteTypeId":
                    sort = new SortExpression(GoodsTravelDaysConfigFields.RouteTypeId | (SortOperator)(int)sortDirection);
                    break;
                case "DeliveryCity":
                    sort = new SortExpression(GoodsTravelDaysConfigFields.DeliveryCity | (SortOperator)(int)sortDirection);
                    break;
                case "GoodsTravelDays":
                    sort = new SortExpression(GoodsTravelDaysConfigFields.GoodsTravelDays | (SortOperator)(int)sortDirection);
                    break;
                case "ReceiptOnWayDays":
                    sort = new SortExpression(GoodsTravelDaysConfigFields.ReceiptOnWayDays | (SortOperator)(int)sortDirection);
                    break;

                default:
                    sort = new SortExpression
                               {
                                   GoodsTravelDaysConfigFields.RouteTypeId | SortOperator.Ascending
                               };
                    sort.Add(GoodsTravelDaysConfigFields.DeliveryCity | SortOperator.Descending);

                    break;

            }
            return sort;
        }

        private IPredicate GetSearchGoodsTravelDaysConfigPredicate(GoodsTravelDaysConfigSearchCriteria criteria)
        {
            var expression = new PredicateExpression();
            if (!string.IsNullOrEmpty(criteria.DeliveryCity))
            {
                expression.Add(GoodsTravelDaysConfigFields.DeliveryCity % ("%" + criteria.DeliveryCity + "%"));
            }

            if (criteria.RouteTypeId.HasValue && criteria.RouteTypeId.Value != Guid.Empty)
            {
                expression.Add(GoodsTravelDaysConfigFields.RouteTypeId == criteria.RouteTypeId);
            }

            if (!string.IsNullOrEmpty(criteria.DeliveryProvince))
            {
                expression.Add(GoodsTravelDaysConfigFields.DeliveryProvince % ("%" + criteria.DeliveryProvince + "%"));
            }

            //if (criteria.AreaId.HasValue && criteria.AreaId.Value != Guid.Empty)
            //{
            //    expression.Add(GoodsTravelDaysConfigFields.AreaId == criteria.AreaId);
            //}

            return expression;
        }



        public bool CheckGoodsTravelDaysConfigExists(Guid id, Guid routeType, string city, Guid areaId)
        {
            var meta = new LinqMetaData();
            bool exist = false;
            if (id != Guid.Empty)
            {
                //update check
                exist = meta.GoodsTravelDaysConfig.Any(a => a.Id != id && a.RouteTypeId == routeType && a.DeliveryCity == city);
            }
            else
            {
                //add check
                exist = meta.GoodsTravelDaysConfig.Any(a => a.RouteTypeId == routeType && a.DeliveryCity == city);
            }
            return exist;
        }
    }
}
